﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FCS.GlobalComponents;
using System.Threading;
using FCS.Communication;

namespace FCS.Pattern
{
    /// <summary>
    /// Manages which controller is running the fountain (either lights/winter or valves)
    /// </summary>
    public class PatternController
    {
        bool _serviceIsRunning = true;
        bool _isRunningFountainPatterns = true;
        object _monitor = new object();
        EventLogWriter _logger = new EventLogWriter("Pattern Controller");
        Thread _patterns;
        FountainController _fountainController;
        LightsController _lightsController;

        // Time range for fountain mode execution
        readonly TimeSpan START_TIME = new TimeSpan(7, 0, 0); // 7 AM
        readonly TimeSpan STOP_TIME = new TimeSpan(22, 0, 0); // 10 PM

        /// <summary>
        /// Controls if the lights or valves are running
        /// </summary>
        /// <param name="isFountainFunning"></param>
        public void StartPattern()
        {
            _patterns = new Thread(() =>
            {
                // prepares controllers for use
                bool areControllersSet = false;
                while (!areControllersSet)
                {
                    try
                    {
                        _fountainController = new FountainController();
                        _lightsController = new LightsController();
                        areControllersSet = true;
                    }
                    catch (Exception ex)
                    {
                        _logger.WriteToLog(System.Diagnostics.EventLogEntryType.Error, "An exception has been thrown during setup!\n" + ex.Message + "\n\n" + ex.InnerException);
                        Thread.Sleep(2000);
                    }
                }

                // the pattern controller will run either the lights or fountain controller until the service is stopped
                while (true)
                {
                    try
                    {
                        bool isRunningFountain = false;

                        lock (_monitor)
                        {
                            isRunningFountain = _isRunningFountainPatterns;
                        }

                        // run the fountain pattern
                        if (isRunningFountain)
                        {
                            _fountainController.RunNextPattern();
                        }
                        else // if not running the fountain patterns, run the lights pattern
                        {
                            _lightsController.RunNextPattern();
                        }

                        bool isServiceRunning = false;
                        lock (_monitor)
                        {
                            isServiceRunning = _serviceIsRunning;
                        }

                        if (!isServiceRunning)
                            break;
                    }
                    catch (Exception ex)
                    {
#if DEBUG
                    _logger.WriteToLog(System.Diagnostics.EventLogEntryType.Error, "An exception has been thrown during exectuion!\n" + ex.Message + "\n\n" + ex.InnerException);
                    Thread.Sleep(2000);
#endif
                        _fountainController = null;
                        _fountainController = new FountainController();
                    }
                }
            });
            _patterns.Start();
        }

        /// <summary>
        /// Switches the mode from fountain to light mode
        /// </summary>
        /// <returns></returns>
        public void SwitchFunctioningMode()
        {
            lock (_monitor)
            {
                _isRunningFountainPatterns = !_isRunningFountainPatterns;
            }
        }

        /// <summary>
        /// Signals the program to stop
        /// </summary>
        public void Stop()
        {
            lock (_monitor)
            {
                _serviceIsRunning = false;
                _patterns.Abort();
                _fountainController.Shutdown();
            }
        }

        /// <summary>
        /// Determins if the fountain should be off
        /// </summary>
        /// <returns></returns>
        private bool IsFountainOff()
        {
            return (DateTime.Now.TimeOfDay < START_TIME || DateTime.Now.TimeOfDay > STOP_TIME);
        }
    }
}
